txt: Xen per-domain S3 integrity config
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 3 Mar 2009 11:52:44 +0000 (11:52 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 3 Mar 2009 11:52:44 +0000 (11:52 +0000)
This patch adds a per-domain flag to specify whether a domain will be
S3 integrity protected when Xen is launched using tboot/TXT.

The tools now support an integer domain configuration parameter called
's3_integrity', which defaults to 1, to enable S3 integrity protection.

The struct arch_domain structure has been extended to have an
's3_integrity' field that represents this setting.

Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
tools/python/xen/xend/XendConfig.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xm/create.py
tools/python/xen/xm/xenapi_create.py
xen/arch/x86/domain.c
xen/arch/x86/setup.c
xen/common/domctl.c
xen/include/asm-x86/domain.h
xen/include/public/domctl.h
xen/include/xen/sched.h

index 4ab49f390f5f0bd3df423d6fafa0cfd10dcacfd9..f62cd856a111d6a026d187fcd880e218d870a90d 100644 (file)
@@ -216,6 +216,7 @@ XENAPI_CFG_TYPES = {
     'cpuid_check' : dict,
     'machine_address_size': int,
     'suppress_spurious_page_faults': bool0,
+    's3_integrity' : int,
 }
 
 # List of legacy configuration keys that have no equivalent in the
index 6189b89f1dd5e96bd978a51c90a01047967a6940..9a217caa68fee3c8ba898148f21e3ccbf5374872 100644 (file)
@@ -2212,12 +2212,15 @@ class XendDomainInfo:
             if security.has_authorization(ssidref) == False:
                 raise VmError("VM is not authorized to run.")
 
+        s3_integrity = self.info['s3_integrity']
+        flags = (int(hvm) << 0) | (int(hap) << 1) | (int(s3_integrity) << 2)
+
         try:
             self.domid = xc.domain_create(
                 domid = 0,
                 ssidref = ssidref,
                 handle = uuid.fromString(self.info['uuid']),
-                flags = (int(hvm) << 0) | (int(hap) << 1),
+                flags = flags,
                 target = self.info.target())
         except Exception, e:
             # may get here if due to ACM the operation is not permitted
index ebff92b749251a152516718bba48c671e3c85f3c..3b4da70451a57136a7b5249071ee48f9780d2587 100644 (file)
@@ -579,6 +579,11 @@ gopts.var('hap', val='HAP',
           use="""Hap status (0=hap is disabled;
           1=hap is enabled.""")
 
+gopts.var('s3_integrity', val='TBOOT_MEMORY_PROTECT',
+          fn=set_int, default=1,
+          use="""Should domain memory integrity be verified during S3?
+          (0=protection is disabled; 1=protection is enabled.""")
+
 gopts.var('cpuid', val="IN[,SIN]:eax=EAX,ebx=EBX,ecx=ECX,edx=EDX",
           fn=append_value, default=[],
           use="""Cpuid description.""")
@@ -832,6 +837,10 @@ def configure_security(config, vals):
     elif num > 1:
         err("VM config error: Multiple access_control definitions!")
 
+def configure_mem_prot(config_image, vals):
+    """Create the config for S3 memory integrity verification under tboot.
+    """
+    config_image.append(['s3_integrity', vals.s3_integrity])
 
 def configure_vtpm(config_devs, vals):
     """Create the config for virtual TPM interfaces.
@@ -964,6 +973,7 @@ def make_config(vals):
             else:
                 config.append(['bootloader_args', '-q'])
     config.append(['image', config_image])
+    configure_mem_prot(config, vals);
 
     config_devs = []
     configure_disks(config_devs, vals)
index 74a534f58c8757cae7d748549e7adc6334ae80fc..5c6333ccb47c62f3b4892449fe63f200988ff0a5 100644 (file)
@@ -269,6 +269,8 @@ class xenapi_create:
                 vm.attributes["is_a_template"].value == 'true',
             "auto_power_on":
                 vm.attributes["auto_power_on"].value == 'true',
+            "s3_integrity":
+                vm.attributes["s3_integrity"].value,
             "memory_static_max":
                 get_child_node_attribute(vm, "memory", "static_max"),
             "memory_static_min":
@@ -650,6 +652,8 @@ class sxp2xml:
             = str(get_child_by_name(config, "vcpus", 1))
         vm.attributes["vcpus_at_startup"] \
             = str(get_child_by_name(config, "vcpus", 1))
+        vm.attributes["s3_integrity"] \
+            = str(get_child_by_name(config, "s3_integrity", 0))
 
         sec_data = get_child_by_name(config, "security")
         if sec_data:
index 5c89eba7ab0963329eb70299c173069e3227ca1b..4d5cc9d75b7ee9a17f7482345bf0a5f9d9853e4c 100644 (file)
@@ -386,6 +386,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
         hvm_funcs.hap_supported &&
         (domcr_flags & DOMCRF_hap);
 
+    d->arch.s3_integrity = !!(domcr_flags & DOMCRF_s3_integrity);
+
     INIT_LIST_HEAD(&d->arch.pdev_list);
 
     d->arch.relmem = RELMEM_not_started;
index be86447c5415285476a0630137dd88eaf4570dc3..8b9427878ed94a8be34a9feb2c30ab10a141e321 100644 (file)
@@ -97,6 +97,7 @@ int early_boot = 1;
 cpumask_t cpu_present_map;
 
 unsigned long xen_phys_start;
+unsigned long allocator_bitmap_end;
 
 #ifdef CONFIG_X86_32
 /* Limits of Xen heap, used to initialise the allocator. */
@@ -418,7 +419,6 @@ void __init __start_xen(unsigned long mbi_p)
     multiboot_info_t *mbi = __va(mbi_p);
     module_t *mod = (module_t *)__va(mbi->mods_addr);
     unsigned long nr_pages, modules_length, modules_headroom;
-    unsigned long allocator_bitmap_end;
     int i, e820_warn = 0, bytes = 0;
     struct ns16550_defaults ns16550 = {
         .data_bits = 8,
@@ -990,7 +990,7 @@ void __init __start_xen(unsigned long mbi_p)
         panic("Could not protect TXT memory regions\n");
 
     /* Create initial domain 0. */
-    dom0 = domain_create(0, 0, DOM0_SSIDREF);
+    dom0 = domain_create(0, DOMCRF_s3_integrity, DOM0_SSIDREF);
     if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
         panic("Error creating domain 0\n");
 
index f4787b22e3a5a74b965dbb6ed1572d8ff7969986..a693dd7ca4720a5ad386a98198177b8f4987063d 100644 (file)
@@ -339,7 +339,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
         ret = -EINVAL;
         if ( supervisor_mode_kernel ||
              (op->u.createdomain.flags &
-             ~(XEN_DOMCTL_CDF_hvm_guest | XEN_DOMCTL_CDF_hap)) )
+             ~(XEN_DOMCTL_CDF_hvm_guest | XEN_DOMCTL_CDF_hap |
+               XEN_DOMCTL_CDF_s3_integrity)) )
             break;
 
         dom = op->domain;
@@ -371,6 +372,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
             domcr_flags |= DOMCRF_hvm;
         if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_hap )
             domcr_flags |= DOMCRF_hap;
+        if ( op->u.createdomain.flags & XEN_DOMCTL_CDF_s3_integrity )
+            domcr_flags |= DOMCRF_s3_integrity;
 
         ret = -ENOMEM;
         d = domain_create(dom, domcr_flags, op->u.createdomain.ssidref);
index f1ea4914a7e36efb809a11554fa4cf63f405ed28..8fc833a2b9b81608e4fe2de99b19a04e223d4eb8 100644 (file)
@@ -221,6 +221,8 @@ struct arch_domain
     unsigned int hv_compat_vstart;
 #endif
 
+    bool_t s3_integrity;
+
     /* I/O-port admin-specified access capabilities. */
     struct rangeset *ioport_caps;
     uint32_t pci_cf8;
index c2845e12f32b395c374c3b88324d53071b6aa25d..d6e47cd0e6588048a7828a67c2d430bf2eac90aa 100644 (file)
@@ -51,11 +51,14 @@ struct xen_domctl_createdomain {
     uint32_t ssidref;
     xen_domain_handle_t handle;
  /* Is this an HVM guest (as opposed to a PV guest)? */
-#define _XEN_DOMCTL_CDF_hvm_guest 0
-#define XEN_DOMCTL_CDF_hvm_guest  (1U<<_XEN_DOMCTL_CDF_hvm_guest)
+#define _XEN_DOMCTL_CDF_hvm_guest     0
+#define XEN_DOMCTL_CDF_hvm_guest      (1U<<_XEN_DOMCTL_CDF_hvm_guest)
  /* Use hardware-assisted paging if available? */
-#define _XEN_DOMCTL_CDF_hap       1
-#define XEN_DOMCTL_CDF_hap        (1U<<_XEN_DOMCTL_CDF_hap)
+#define _XEN_DOMCTL_CDF_hap           1
+#define XEN_DOMCTL_CDF_hap            (1U<<_XEN_DOMCTL_CDF_hap)
+ /* Should domain memory integrity be verifed by tboot during Sx? */
+#define _XEN_DOMCTL_CDF_s3_integrity  2
+#define XEN_DOMCTL_CDF_s3_integrity   (1U<<_XEN_DOMCTL_CDF_s3_integrity)
     uint32_t flags;
 };
 typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
index 24a75552d09619c71bc12dbe4037335918b4c9b8..f859849da650fd9aae1559de72a8041be6d382ec 100644 (file)
@@ -341,14 +341,18 @@ static inline struct domain *get_current_domain(void)
 struct domain *domain_create(
     domid_t domid, unsigned int domcr_flags, ssidref_t ssidref);
  /* DOMCRF_hvm: Create an HVM domain, as opposed to a PV domain. */
-#define _DOMCRF_hvm   0
-#define DOMCRF_hvm    (1U<<_DOMCRF_hvm)
+#define _DOMCRF_hvm           0
+#define DOMCRF_hvm            (1U<<_DOMCRF_hvm)
  /* DOMCRF_hap: Create a domain with hardware-assisted paging. */
-#define _DOMCRF_hap   1
-#define DOMCRF_hap    (1U<<_DOMCRF_hap)
+#define _DOMCRF_hap           1
+#define DOMCRF_hap            (1U<<_DOMCRF_hap)
+ /* DOMCRF_s3_integrity: Create a domain with tboot memory integrity protection
+                        by tboot */
+#define _DOMCRF_s3_integrity  2
+#define DOMCRF_s3_integrity   (1U<<_DOMCRF_s3_integrity)
  /* DOMCRF_dummy: Create a dummy domain (not scheduled; not on domain list) */
-#define _DOMCRF_dummy 2
-#define DOMCRF_dummy  (1U<<_DOMCRF_dummy)
+#define _DOMCRF_dummy         3
+#define DOMCRF_dummy          (1U<<_DOMCRF_dummy)
 
 /*
  * rcu_lock_domain_by_id() is more efficient than get_domain_by_id().